#!/usr/local/bin/perl -w
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
# 
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
# 
# The Original Code is Komodo code.
# 
# The Initial Developer of the Original Code is ActiveState Software Inc.
# Portions created by ActiveState Software Inc are Copyright (C) 2000-2007
# ActiveState Software Inc. All Rights Reserved.
# 
# Contributor(s):
#   ActiveState Software Inc
# 
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
# 
# ***** END LICENSE BLOCK *****

use File::Basename qw(basename);

Import(
    "cons",
    "build",
    "platform",
    "buildType", "buildFlavour",
    "buildPlatform",
    "updateChannel",
    "buildPlatform",
    "compiler",
    "komodoDevDir",
    "unsiloedPythonExe",
    "ranRegxpcomStateFileName",
    "mozObjDir",
    "mozApp",
    "mozSrc",
    "mozBin",
    "mozExe",
    "mozComponentsDir",
    "mozIdlIncludePath",
    "mozChromeDir",
    "mozResourcesDir",
    'mozDevelDist',
    "mozVersion",
    "mozVersionNumber",
    "mozGreMilestone",
    "mozMake",
    "idlExportDir",
    "version",
    "komodoVersion",
    "komodoShortVersion",
    "komodoMarketingShortVersion",
    "komodoFullPrettyVersion",
    "komodoAppDataDirName",
    "komodoUpdateManualURL",
    "buildNum",
    "siloedPyVer",
    "komodoPythonUtilsDir",
    "productType",
    "prettyProductType",
    "isGTK2Siloed",
    "stubDir",
    "envScriptName",
    "unsiloedPerlBinDir",
);


# keep debug and release Komodo root files separated by name
my $suffix = "";
if ($buildType eq 'debug') {
    $suffix = "_d";
}

my $currYear = (localtime(time))[5] + 1900;


# Install the necessary PNG files for GTK alt-tabbing UI (bug 80727).
# TODO: Eventually this could be integrated with the
#       $mozSrc/komodo/Makefile.in build as is done for mozilla/browser.
if ($platform ne "win" && $platform ne "darwin") { # i.e. GTK
    $cons->InstallAs("$mozBin/chrome/icons/default/default16.png",
                     "komodo16.$productType.png");
    $cons->InstallAs("$mozBin/chrome/icons/default/default32.png",
                     "komodo32.$productType.png");
    $cons->InstallAs("$mozBin/chrome/icons/default/default48.png",
                     "komodo48.$productType.png");
    $cons->InstallAs("$mozBin/chrome/icons/default/default.png",
                     "komodo128.$productType.png");
}

# Install these images into the Komodo chrome, so the application UI can make
# use of them as well.
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_16x16.png",
                 "komodo16.$productType.png");
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_32x32.png",
                 "komodo32.$productType.png");
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_48x48.png",
                 "komodo48.$productType.png");
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_64x64.png",
                 "komodo64.$productType.png");
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_128x128.png",
                 "komodo128.$productType.png");
$cons->InstallAs("$mozBin/chrome/komodo/skin/images/komodo_256x256.png",
                 "komodo256.$productType.png");


# XRE-based Komodo startup:
# With the move to Firefox and the XRE, there is no longer a
# separation of komodo startup shim (a.k.a. komodo.c) and the main
# Mozilla executable. They are now the same. The startup executable
# is necessarily built as part of the Mozilla build
# ($MOZ_SRC/komodo/...). The Mozilla-devel source tree is setup with
# placeholders for the bits that actually handle the Komodo startup
# gymnastics (e.g. commandments, ensuring one Komodo instance). Here
# in the Komodo-devel build the plan is to (1) drop in the properly
# configured bits; and (2) rebuild that part of the Firefox source
# tree.

my ($cp, $buildCmd, $mozKomodoSrcDir, $mozKomodoObjDir,
    $macKoIconName, $envVars, $productName);

if ($buildFlavour eq "full") {
    $macKoIconName = "komodo.$productType";
} else {
    # Use a different icon for dev-builds to differentiate in the Dock.
    $macKoIconName = "komodo_eye";
}

$komodoVersion =~ /(\d+)\.(\d+)\.(\d+)/;
$koMajor = $1;
$koMinor = $2;
$koPatch = $3;
$komodoAppUpdateEnabled = ($buildFlavour eq "dev" ? "false" : "true");
$productName = ($productType eq "openkomodo"
                ? "OpenKomodo"
                : "Komodo $prettyProductType");

my %ppData = (
    'PP_KO_MAJOR' => $koMajor,
    'PP_KO_MINOR' => $koMinor,
    'PP_KO_PATCH' => $koPatch,
    'PP_KO_PRETTY_PROD_TYPE' => "$prettyProductType",
    'PP_KO_SHORT_VERSION' => "$komodoShortVersion",
    'PP_KO_MARKETING_SHORT_VERSION' => "$komodoMarketingShortVersion",
    'PP_KO_FULL_PRETTY_VERSION' => "$komodoFullPrettyVersion",
    'PP_KO_BUILD_PLATFORM' => "$buildPlatform",
    'PP_KO_PROD_TYPE' => "$productType",
    'PP_KO_PROD_NAME' => "$productName",
    'PP_KO_APPDATADIR_NAME' => "$komodoAppDataDirName",
    'PP_KO_VERSION' => "$komodoVersion",
    'PP_KO_UPDATE_MANUAL_URL' => "$komodoUpdateManualURL",
    'PP_KO_APP_UPDATE_ENABLED' => "$komodoAppUpdateEnabled",
    'PP_KO_BUILD_NUMBER' => "$buildNum",
    'PP_KO_IS_DEV_BUILD' => ($buildFlavour eq "dev") ? 1 : 0,
    'PP_KO_UPDATE_CHANNEL' => "$updateChannel",
    'PP_KO_PLATNAME' => "$buildPlatform",
    'PP_PYTHON_MAJOR_MINOR' => "$siloedPyVer",
    'PP_IS_GTK2_SILOED' => "$isGTK2Siloed",
    'PP_COMPILER' => "$compiler",
    'PP_CURR_YEAR' => "$currYear",
    'PP_MOZ_GRE_MILESTONE' => "$mozGreMilestone",
    'PP_GRE_MILESTONE' => "$mozGreMilestone",
);


if ($platform eq "win") {
    $cp = "copy";
    $mozKomodoSrcDir = "$mozSrc\\mozilla\\komodo";
    $mozKomodoObjDir = "$mozObjDir\\komodo\\app";
    if ($buildFlavour eq "dev") {
        $envVars = "MOZ_WINCONSOLE=1";
    } else {
        #XXX This should depend on a configure option other than
        #    --dev/--full.
        $envVars = "MOZ_WINCONSOLE=0";
    }
    $envVars .= " KOMODO_USE_WMAIN=1";
    #$unsiloedPerlExe =~ s/\\/\//g;
    #$envVars .= " PERL=$unsiloedPerlExe";
    #$buildCmd = "cd $mozKomodoSrcDir\\app && touch *.c && touch *.cpp && cd $mozKomodoObjDir\\app && del *.obj && $mozMake $envVars";
    my $mozSrcMsys = $mozSrc;
    $mozSrcMsys =~ s/\\/\//g;
    my $mozObjDirMsys = $mozObjDir;
    $mozObjDirMsys =~ s/\\/\//g;
    my $envScriptMsys = $envScriptName;
    $envScriptMsys =~ s/\\/\//g;
    $envScriptMsys =~ s/\.bat$/.sh/;
    $mozPython = "$mozObjDirMsys/_virtualenv/Scripts/python.exe";
    $buildCmd = qq(cd $mozKomodoSrcDir\\app &&
                   touch *.c *.cpp &&
                   call $envScriptName &&
                   $ENV{MOZILLABUILD}\\msys\\bin\\bash --login -c "
                        unset PYTHONPATH &&
                        unset PYTHONHOME &&
                        cd $mozSrcMsys/mozilla &&
                        export NUMBER_OF_PROCESSORS=$ENV{NUMBER_OF_PROCESSORS} &&
                        ./mach -v build -v komodo/app
                    ");
    $buildCmd =~ s/\r?\n//g;
} else {
    $cp = "cp -f";
    $mozKomodoSrcDir = "$mozSrc/mozilla/komodo";
    $mozKomodoObjDir = "$mozObjDir/komodo/app";
    # Mozilla will use it's own virtualenv Python - we must set it's home
    # directory, else it will complain about being unable to find modules.
    my $pythonHome = "$mozObjDir/_virtualenv";
    $buildCmd = "cd $mozKomodoObjDir && rm -f my_getopt.o koStart.o && make PYTHONHOME='" . $pythonHome . "'";
}

my @xreFiles = (
    # <action>, <src>, <dest>
    #   where "dest" defaults to "src" if undefined.
    # Here the "+share" actions mean to copy the file over to the main/stub
    # directory where it will also be used for the stub.
    ["cp+share",         'app/getopt.h', undef],
    ["cp+share",         'app/my_getopt.h', undef],
    ["cp+share",         'app/my_getopt.c', undef],
    ["preprocess+share", 'app/nsKomodoApp.p.cpp', 'app/nsKomodoApp.cpp'],
    ["cp+share",         'app/koStart.h', undef],
    ["preprocess+share", 'app/koStart.p.c', 'app/koStart.c'],
    ["preprocess+share", 'app/komodo.exe.p.manifest', 'app/komodo.exe.manifest'],
    #XXX Might need a ko.exe.manifest as well.

    ["preprocess",       'app/module.p.ver','app/module.ver'],
    ["preprocess",       'app/splash.p.rc', 'app/splash.rc'],

    ["preprocess",       'app/macbuild/Contents/Info.p.plist.in',
                         'app/macbuild/Contents/Info.plist.in'],
    ["preprocess",       'app/profile/komodo.p.js', 'app/profile/komodo.js'],

    ["preprocess",       'config/version.p.txt', 'config/version.txt'],

    ["preprocess",       "app/brand.p.dtd", "app/brand.dtd"],
    ["preprocess",       "app/brand.p.properties", "app/brand.properties"],

    ["preprocess",       "app/application.p.ini.h", "app/komodo_application.ini.h"],

    #TODO: Add ko_project.ico.
    ["cp",               "app/komodo.$productType.ico", "app/komodo.ico"],
    ["cp",               "app/macbuild/$macKoIconName.icns",
                         "app/macbuild/komodo.icns"],
    ["cp",               "../komodo16.$productType.xpm", "app/default.xpm"],
);

if ($platform eq "darwin" && $mozVersionNumber >= 3500) {
    # Objective-C code.
    push(@xreFiles, ["preprocess+share", 'app/koStart.p.c', 'app/koStart.mm']);
} else {
    push(@xreFiles, ["preprocess+share", 'app/koStart.p.c', 'app/koStart.c']);
}

foreach my $xreFileData_ref (@xreFiles) {
    my @xreFileData = @$xreFileData_ref;
    my $action = $xreFileData[0];
    my $src = $xreFileData[1];
    my $dest = $xreFileData[2];
    if (! $dest) {
        $dest = $src;
    }

    if ($action eq "cp" || $action eq "cp+share") {
        $cons->Command("$mozKomodoSrcDir/$dest",
                       "xre/$src",
                       qq(
                        $cp %1 %0
                       ));
        if ($action eq "cp+share") {
            $cons->Command("stub/".basename($dest),
                           "xre/$src",
                           qq(
                            $cp %1 %0
                           ));
        }
    }
    elsif ($action eq "preprocess" || $action eq "preprocess+share") {
        $cons->Preprocess("xre/$src", "xre/$dest", \%ppData);
        $cons->InstallAs("$mozKomodoSrcDir/$dest", "xre/$dest");
        if ($action eq "preprocess+share") {
            $cons->InstallAs("stub/".basename($dest), "xre/$dest");
        }
    }
    else {
        die "unknown XRE data action: '$action'\n";
    }
    $cons->Depends($mozExe, "$mozKomodoSrcDir/$dest");
}

# Some XRE files aren't handled by the mozilla/komodo/.../Makefile's,
# so we need to do the copy to .../dist/bin ourselves here.
$cons->Preprocess("xre/app/profile/channel-prefs.p.js",
                  "xre/app/profile/channel-prefs.js", \%ppData);
$cons->Install("$mozBin/defaults/pref", "xre/app/profile/channel-prefs.js");

$cons->Preprocess("xre/app/application.p.ini",
                  "$mozBin/application.ini", \%ppData);

my $buildOutputs;
if ($platform eq "win" || $platform eq "darwin") {
    $buildOutputs = ["$mozExe"];
} else {
    $buildOutputs = ["$mozExe", "$mozChromeDir/icons/default/default.xpm"];
}
$cons->Command($buildOutputs, $buildCmd);
# Make sure we run before the regxpcom process (which currently tries to
# do this build). (XXX Not sure this is necessary any more.)
$cons->Depends($ranRegxpcomStateFileName, $mozExe);

if ($platform eq "darwin") {
    # need to rebuild the PkgInfo file to have a matching application ID
    $cons->Command("$mozApp/Contents/PkgInfo",
                   "$mozKomodoSrcDir/app/macbuild/Contents/Info.plist.in",
                   "$mozExe",
                   # the printf splits the %s on purpose to get around cons :/
                   qq(
                    printf "APPL%"s `grep -A1 CFBundleSignature %1 | tail -n1 | cut -d '<' -f 2 | cut -d '>' -f 2` > %0
                   ));
}

if ($platform eq "win") {
    # Build the Komodo stub exe for Windows
    #XXX May want to build a komodow.exe for double-clicking as well.

    # copy over the Unicode handling helper
    $cons->Command(
        "stub/nsWindowsWMain.cpp",
        "$mozSrc/mozilla/toolkit/xre/nsWindowsWMain.cpp",
        qq(
            $cp %1 %0
        ));

    # Preprocess the Komodo resource file.
    #XXX Technically using our $buildNum (which is the Perforce change
    #    number) is not valid for a Windows file version string: each
    #    numeric element is limited to 65535 (I think that was it, the
    #    exact number is somewhere in MSI) and ours is over this limit.
    #    This *could* surprise us with MSI upgrades at some point.
    my $FILEVERSION = $komodoVersion;
    $FILEVERSION =~ s/-.*$//g; # drop potential non-numeric bit: "-alpha1"
    $FILEVERSION .= '.' . $buildNum;
    $FILEVERSION =~ s/[.-]/, /g;
    my %rcData = (
        'PP_KO_VERSION' => "$komodoVersion-$buildNum",
        'PP_KO_COMMASEP_VERSION' => $FILEVERSION, # must all be numeric
        'PP_CURR_YEAR' => "$currYear",
    );
    $cons->Preprocess("stub/komodo.p.rc", "stub/komodo.rc",
                      \%rcData);

    $cons->InstallAs("xre/app/komodo.ico",
                     "xre/app/komodo.$productType.ico");

    # Build the Komodo starter stub (ko.exe: console, komodo.exe: windows)
    my $CFLAGS = " /W3 /Ox /DNDEBUG /D_NDEBUG /DWIN32 /DXP_WIN /DXRE_DONT_PROTECT_DLL_LOAD /MT /Zi";
    my $stub_CFLAGS = " -DMOZ_NO_MOZALLOC -TP -I$mozObjDir/dist/include -FI $mozObjDir/dist/include/mozilla-config.h";
    # XRE_DONT_SUPPORT_XPSP2 - to avoid include a bunch of useless header defines.
    $stub_CFLAGS .= ' -DXRE_DONT_SUPPORT_XPSP2';
    my $LDFLAGS = "kernel32.lib user32.lib gdi32.lib advapi32.lib shlwapi.lib ws2_32.lib shell32.lib";
    $cons->Command(
        "stub/ko.exe",                  # 0
        "stub/komodo.c",                # 1
        "stub/komodo.rc",               # 2
        "xre/app/komodo.ico",           # 3
        "xre/app/ko_project.ico",       # 4
        "xre/app/guibuilder_ui.ico",    # 5
        "stub/koStart.c",               # 6
        "stub/koStart.h",               # 7
        "stub/my_getopt.c",             # 8
        "stub/komodo.exe.manifest",     # 9
        "stub/getopt.h",                # 10
        "stub/my_getopt.h",             # 11
        "stub/nsWindowsWMain.cpp",      # 12
        qq(
            copy %3 %0:d
            copy %4 %0:d
            copy %5 %0:d
            cl /nologo $CFLAGS $stub_CFLAGS /D_CONSOLE /D_MBCS /Fo%1:b.obj /c %1
            cl /nologo $CFLAGS /D_CONSOLE /D_MBCS /Fo%6:b.obj /c %6
            cl /nologo $CFLAGS /D_CONSOLE /D_MBCS /Fo%8:b.obj /c %8
            rc /fo%2:b.res %2
            link /nologo $LDFLAGS /debug /subsystem:console /out:%0 %1:b.obj %6:b.obj %8:b.obj %2:b.res
            mt -manifest %9 -outputresource:%0
        )
    );
    $cons->Install($stubDir, "stub/ko.exe");

    $cons->Command(
        "stub/komodo.exe",              # 0
        "stub/komodo.c",                # 1
        "stub/komodo.rc",               # 2
        "xre/app/komodo.ico",           # 3
        "xre/app/ko_project.ico",       # 4
        "xre/app/guibuilder_ui.ico",    # 5
        "stub/koStart.c",               # 6
        "stub/koStart.h",               # 7
        "stub/my_getopt.c",             # 8
        "stub/komodo.exe.manifest",     # 9
        "stub/getopt.h",                # 10
        "stub/my_getopt.h",             # 11
        "stub/nsWindowsWMain.cpp",      # 12
        qq(
            copy %3 %0:d
            copy %4 %0:d
            copy %5 %0:d
            cl /nologo $CFLAGS $stub_CFLAGS /D_WINDOWS /Fo%1:b.obj /c %1
            cl /nologo $CFLAGS /D_WINDOWS /Fo%6:b.obj /c %6
            cl /nologo $CFLAGS /D_WINDOWS /Fo%8:b.obj /c %8
            rc /fo%2:b.res %2
            link /nologo $LDFLAGS /debug /subsystem:windows /out:%0 %1:b.obj %6:b.obj %8:b.obj %2:b.res
            mt -manifest %9 -outputresource:%0
        )
    );
    $cons->Install($stubDir, "stub/komodo.exe");
}
elsif ($platform eq "darwin") {
    # There is currently no starter stub on Mac OS X.
}
else {
    # Install the Linux/Solaris start stub.
    $cons->Install($stubDir, "stub/komodo");
}
